<template>
	<div class="publish">
		<!-- 面包屑 -->
		<el-breadcrumb separator-class="el-icon-arrow-right">
			<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
			<el-breadcrumb-item><router-link to="/">文章管理</router-link></el-breadcrumb-item>
			<el-breadcrumb-item>添加文章</el-breadcrumb-item>
		</el-breadcrumb>
		<!-- 卡片 -->
		<el-card class="card" shadow="hover">
			<!-- 表单 -->
			<el-form
				label-width="auto"
				:rules="rules"
				hide-required-asterisk
				:model="form"
				ref="form"
			>
				<!-- 标题 -->
				<el-form-item label="标题" prop="title">
					<el-input v-model="form.title" show-word-limit clearable></el-input>
				</el-form-item>
				<!-- 单选框 -->
				<el-form-item label="类型" prop="type">
					<el-radio v-model="form.type" :label="1">文章</el-radio>
					<el-radio v-model="form.type" :label="2">视频</el-radio>
				</el-form-item>
				<!-- 文章内容 -->
				<el-form-item label="内容">
					<!-- 富文本外部插件 - https://github.com/hsian/vue-word-editor -->
					<VueEditor v-show="form.type == 1" :config="editorConfig" ref="vueEditor" />
					<!-- 上传视频 -->
					<el-upload
						v-show="form.type == 2"
						class="upload-demo"
						:action="$baseURL + '/upload'"
						:limit="1"
						:headers="token"
						:before-upload="videoCheckFn"
						:on-success="videoSuccessFn"
						:on-remove="videoRemoveFn"
						:file-list="videoList"
					>
						<el-button size="small" type="primary">点击上传</el-button>
						<div slot="tip" class="el-upload__tip">只能上传MP4文件，且不超过1MB</div>
					</el-upload>
				</el-form-item>

				<!-- 复选框 -->
				<el-form-item label="栏目">
					<!-- 全选控件 -->
					<!-- 
						indeterminate - 不确定状态
						v-model - 布尔状态
						label - 标题和值
					 -->
					<el-checkbox
						:indeterminate="isIndeterminate"
						v-model="isAll"
						@change="totalBoxFn"
					>
						全选
					</el-checkbox>
				</el-form-item>
				<el-form-item prop="categories">
					<!-- 复选框组 -->
					<!-- 
						min - 最小选择数量
						v-model - 选中数组（label）
					 -->
					<el-checkbox-group v-model="form.categories" :min="1" @change="groupBoxFn">
						<el-checkbox v-for="item in categoryList" :key="item.id" :label="item.id">
							{{ item.name }}
						</el-checkbox>
					</el-checkbox-group>
				</el-form-item>
				<!-- 图片上传 -->
				<el-form-item label="封面">
					<!-- 
						action - 上传地址（必选）
						headers - 上传头部
						list-type - 文件列表类型
						drag - 拖拽上传
						limit - 最大上传数量
						multiple - 开启多选
						
						on-exceed - 超出 limit 数量触发
						before-upload - 上传完毕前触发，return false 可终止上传
						on-change - 无论上传成功与否都触发
						on-remove - 移除触发
						on-success - 上传成功触发
					 -->
					<el-upload
						class="image-uploader"
						:action="$baseURL + '/upload'"
						:headers="token"
						list-type="picture-card"
						:limit="3"
						multiple
						:on-exceed="overflowFn"
						:before-upload="beforeUploadFn"
						:on-change="onChangeFn"
						:on-remove="onRemoveFn"
						:on-success="onSuccessFn"
						:class="{ 'hide-uploader': isFull }"
						:file-list="coverList"
					>
						<i class="el-icon-plus"></i>
					</el-upload>
				</el-form-item>
				<!-- 提交 -->
				<el-form-item>
					<el-button :type="$route.query.id ? 'success' : 'primary'" @click="submitFn">
						提交{{ $route.query.id ? '编辑' : '发布' }}
					</el-button>
				</el-form-item>
			</el-form>
		</el-card>
	</div>
</template>

<script>
import VueEditor from 'vue-word-editor';
import 'quill/dist/quill.snow.css';
import { getCategoryAPI } from '@/api/category.js';
import { getToken } from '@/utils/localStorage.js';
import { publishPostAPI, getArticleAPI, editArticleAPI } from '@/api/article.js';
export default {
	components: {
		VueEditor
	},
	data() {
		return {
			// 表单数据
			form: {
				title: '', // 标题
				type: '1', // 类型id
				categories: [], // 所属栏目 id 数组
				content: '', // 富文本内容
				cover: [] //封面图片 id 数组
			},
			// 表单规则校验
			rules: {
				title: [
					{ required: true, message: '请输入标题', trigger: 'blur' },
					{
						min: 3,
						max: 20,
						message: '长度在 3 到 20 个字符',
						trigger: 'blur'
					}
				],
				type: [{ required: true, message: '请选择类型', trigger: 'change' }],
				categories: [{ required: true, message: '请选择栏目', trigger: 'change' }]
			},
			isIndeterminate: true, // 复选框不确定态
			isAll: false, // 复选框全选态
			editorConfig: {
				// 富文本配置
				uploadImage: {
					url: `${this.$baseURL}/upload`,
					headers: {
						Authorization: getToken()
					},
					name: 'file',
					// res是结果，insert方法会把内容注入到编辑器中，res.data.url是资源地址
					uploadSuccess: (res, insert) => {
						// console.log(res.data);
						const { message } = res.data;
						if (message !== '文件上传成功') return this.$message.fail(message);
						this.$message.success(message);
						insert(this.$baseURL + res.data.data.url);
					}
				},
				// 上传视频的配置
				uploadVideo: {
					url: 'http://localhost:3000/upload',
					name: 'file',
					uploadSuccess(res, insert) {
						insert('http://localhost:3000' + res.data.url);
					}
				}
			},
			categoryList: [], // 栏目列表
			token: { Authorization: getToken() }, // 上传图片请求头
			isFull: false, // 上传图片限制
			videoList: [],
			coverList: []
		};
	},
	async created() {
		this.categoryList = (await getCategoryAPI()).data.data;
		this.categoryList.splice(0, 2);
		// console.log(this.$route);
		const { id } = this.$route.query;
		// 新建文章页面
		if (!id) return this.form.categories.push(this.categoryList[0].id);
		// 修改文章页面
		if (id) {
			const res = (await getArticleAPI(id)).data.data;
			console.log(res);
			// 表单数据填充
			this.form = {
				title: res.title,
				type: res.type,
				categories: res.categories.map(item => item.id),
				content: res.content,
				cover: res.cover.map(item => ({ id: item.id }))
			};
			// 封面填充
			res.cover.map(item =>
				this.coverList.push({ id: item.id, url: this.$baseURL + item.url })
			);
			if (res.cover.length >= 3) this.isFull = true;

			// 视频和富文本内容填充
			if (res.type == 1)
				this.$refs.vueEditor.editor.clipboard.dangerouslyPasteHTML(0, `${res.content}`);
			if (res.type == 2) this.videoList.push({ name: 'mp4视频', url: res.content });
		}
		// console.log(this.categoryList);
	},
	methods: {
		// 提交按钮
		submitFn() {
			// 富文本赋值
			if (this.form.type == 1) this.form.content = this.$refs.vueEditor.editor.root.innerHTML;
			// 数据检查
			const form = this.form;
			if (form.title.trim() === '') return this.$message.waring('标题不规范');
			if (form.categories.length <= 0) return this.$message.waring('至少选择一个栏目');
			if (form.cover.length <= 0) return this.$message.waring('至少上传一个封面');
			if (form.content == '<p><br></p>' || form.content == '')
				return this.$message.waring('新闻内容不能为空');

			form.categories = form.categories.map(item => ({ id: item }));

			// 确认弹窗
			this.$confirm('确认提交？', '提示', {
				confirmButtonText: '提交',
				cancelButtonText: '取消',
				type: 'info'
			})
				.then(() => {
					this.$refs.form.validate(async valid => {
						// 安全阻断
						if (!valid) return this.$message.error('还有未完成的地方');
						const { id } = this.$route.query;
						const { message } = id
							? (await editArticleAPI(id, form)).data
							: (await publishPostAPI(form)).data;
						// 安全阻断
						// console.log(message);
						if (message !== '文章发布成功' && message !== '文章编辑成功')
							return this.$message.error(message);
						// 提交跳转
						this.$message.success(message);
						this.$router.push('/article');
					});
				})
				.catch(() => this.$message.info('取消操作'));
		},
		// 校验视频
		videoCheckFn(file) {
			// console.log(file.type);
			if (file.type !== 'video/mp4' || file.size >= 1024 * 1024) {
				this.$message.warning('视频不符合要求！');
				return false;
			}
		},
		// 上传视频成功
		videoSuccessFn(res) {
			console.log(res);
			if (res.message !== '文件上传成功') return this.$message.warning(res.message);
			this.$message.success(res.message);
			this.form.content = this.$baseURL + res.data.url;
		},
		// 移除视频触发
		videoRemoveFn(file, fileList) {
			this.form.content = '';
		},
		// 上传封面成功
		onSuccessFn(res) {
			// console.log(res);
			if (res.message !== '文件上传成功') return this.$message.warning(res.message);
			this.$message.success(res.message);
			this.form.cover.push({ id: res.data.id });
		},
		// 上传文件数量限制
		onChangeFn(file, fileList) {
			// console.log(fileList);
			this.isFull = fileList.length >= 3 ? true : false;
		},
		// 移除方法
		onRemoveFn(file, fileList) {
			// console.log(file);
			this.isFull = fileList.length >= 3 ? true : false;
			const id = file.response ? file.response.data.id : file.id;
			this.form.cover = this.form.cover.filter(item => item.id !== id);
		},
		// 上传校验文件类型
		beforeUploadFn(file) {
			console.log(file.type);
			const type = ['image/jpeg', 'image/x-icon', 'image/png', 'image/jpg'];
			if (type.indexOf(file.type) === -1) {
				this.$message.warning('请选择图片！');
				return false;
			}
		},
		// 上传溢出
		overflowFn() {
			this.$message.warning('最多只能上传三张！');
		},
		// 小选控制全选
		groupBoxFn(val) {
			// 分支写法
			// if (val.length === this.categoryList.length) {
			// 	this.form.isAll = true;
			// 	this.form.isIndeterminate = false;
			// } else {
			// 	this.form.isAll = false;
			// 	this.form.isIndeterminate = true;
			// }
			// 三元写法
			const res = val.length === this.categoryList.length;
			this.isAll = res;
			this.isIndeterminate = !res;
		},
		// 全选控制小选
		totalBoxFn(val) {
			this.isIndeterminate = !val;
			if (val) this.form.categories = this.categoryList.map(item => item.id);
			else {
				this.form.categories.length = 0;
				this.form.categories.push(this.categoryList[0].id);
			}
		}
	}
};
</script>

<style scoped lang="less">
.card {
	margin-top: 20px;
}
.image-uploader .el-upload {
	border: 1px dashed #d9d9d9;
	border-radius: 6px;
	cursor: pointer;
	position: relative;
	overflow: hidden;
}
.image-uploader .el-upload:hover {
	border-color: #409eff;
}
.image-uploader-icon {
	font-size: 28px;
	color: #8c939d;
	width: 178px;
	height: 178px;
	line-height: 178px;
	text-align: center;
}
</style>
<style lang="less">
/* 隐藏上传按钮 */
.hide-uploader .el-upload--picture-card {
	display: none;
}
</style>
